package com.neusoft.databus.sap.listener;

import java.util.Arrays;

import javax.jms.ConnectionFactory;
import javax.jms.ObjectMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import com.neusoft.bizcore.common.bean.MessageBean;
import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.databus.core.service.ResourceService;
import com.neusoft.databus.policy.enums.EventStatus;
import com.neusoft.databus.policy.enums.PolicyType;
import com.neusoft.databus.policy.model.Policy;
import com.neusoft.databus.policy.repository.PolicyRepository;
import com.neusoft.databus.policy.vo.EventVO;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
@ConditionalOnClass({ConnectionFactory.class, ActiveMQConnectionFactory.class })
@ConditionalOnProperty(name = "databus.core.linkage.enabled", havingValue = "true")
public class PolicyEventActiveMqListener {

    @Autowired
    private PolicyRepository PolicyRepository;

    @Autowired
    private ResourceService resourceService;

    @JmsListener(destination = "${databus.policy.eventTopic}")
    public void processPolicyEvent(ObjectMessage message) {
        try {
            final MessageBean messageBean = (MessageBean) message.getObject();
            final EventVO event = JsonUtils.jsonToPojo(messageBean.getMessage(), EventVO.class);
            PolicyEventActiveMqListener.log.info("receive a policy event {}-{}-{} from activemq",
                    event.getResourceCode(), event.getStatus(), event.getContent());

            if (!PolicyType.POLICY_ALARM.equals(event.getType())) {
                return;
            }
            if (EventStatus.UNFIXED.equals(event.getStatus())) {
                this.linkageControl(event.getPolicyCode());
            } else {
                this.linkageCancel(event.getPolicyCode());
            }
        } catch (final Exception e) {
            PolicyEventActiveMqListener.log.error(e.getMessage(), e);
        } finally {
            message = null;
        }

    }

    private void linkageControl(String policyCode) {
        final Policy policy = this.PolicyRepository.findByCode(policyCode);
        policy.getPolicyRefLinkages().forEach(it -> {
            if (!StringUtils.isEmpty(it.getControlUsageMetrics())) {
                Arrays.asList(it.getControlUsageMetrics().split(",")).forEach(metric -> {
                    try {
                        this.resourceService.control(it.getResourceCode(), metric);
                    } catch (final Exception e) {
                        PolicyEventActiveMqListener.log.error("", e);
                    }
                });
            }

        });
    }

    private void linkageCancel(String policyCode) {
        final Policy policy = this.PolicyRepository.findByCode(policyCode);
        policy.getPolicyRefLinkages().forEach(it -> {
            if (!StringUtils.isEmpty(it.getCancelUsageMetrics())) {
                Arrays.asList(it.getCancelUsageMetrics().split(",")).forEach(metric -> {
                    try {
                        this.resourceService.control(it.getResourceCode(), metric);
                    } catch (final Exception e) {
                        PolicyEventActiveMqListener.log.error("", e);
                    }
                });
            }

        });
    }
}
